package cn.edu.njnu.opengmpback.common.utils;
import cn.edu.njnu.opengmpback.common.JSch.JSchConnectionManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import com.jcraft.jsch.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.stereotype.Service;

import java.io.*;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;

@Service
public class FTPFileTransferService {

    @Autowired
    JSchConnectionManager jschConnectionManager;

    @Qualifier("webApplicationContext")
    @Autowired
    private ResourceLoader resourceLoader;

    //上传单个文件到远程
    public void transferFileToRemoteDockerContainer(String localFilePath, String remoteFilePath) throws Exception {
        Session session = jschConnectionManager.getSession();
        // 上传文件到远程主机
        ChannelSftp channel = (ChannelSftp) session.openChannel("sftp");
        channel.connect();
        // 读取本地文件
        Path filePath = Paths.get(localFilePath);
        FileInputStream fis = new FileInputStream(filePath.toFile());

        // 上传文件到远程服务器
        channel.put(fis, remoteFilePath);
        channel.disconnect();
    }
    //上传多个文件到远程
    public void transferFilesToRemoteDockerContainer(List<Map<String, String>> transfer) throws Exception {
        Session session = jschConnectionManager.getSession();
        ChannelSftp channel = (ChannelSftp) session.openChannel("sftp");
        channel.connect();
        for (Map<String, String> map : transfer) {
            String localFilePath = map.get("filePath");
            String remoteFilePath = map.get("destPaths");
            try {
                // 读取本地文件
                Path filePath = Paths.get(localFilePath);
                FileInputStream fis = new FileInputStream(filePath.toFile());

                // 上传文件到远程服务器
                channel.put(fis, remoteFilePath);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        channel.disconnect();
    }

    private void uploadDirectory(ChannelSftp channelSftp, String resourcePath, String remotePath) throws SftpException, IOException {
        // 使用 PathMatchingResourcePatternResolver 来处理 JAR 文件中的资源
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        Resource[] resources = resolver.getResources("classpath:" + resourcePath + "/**");

        // 在远程服务器上创建目录
        try {
            channelSftp.cd(remotePath);
        } catch (SftpException e) {
            channelSftp.mkdir(remotePath);
            channelSftp.cd(remotePath);
        }

        // 遍历并上传每个资源
        for (Resource resource : resources) {
            if (resource.isReadable()) {
                if (resource.getFilename().endsWith("/")) {
                    // 如果是目录，递归调用此方法
                    uploadDirectory(channelSftp, resource.getFilename(), remotePath + "/" + resource.getFilename());
                } else {
                    // 上传文件
                    try (InputStream fis = resource.getInputStream()) {
                        channelSftp.put(fis, remotePath + "/" + resource.getFilename());
                    }
                }
            }
        }
    }

    public List<String> transferFilesToLocal(List<String> filePaths, String localFileDir) throws Exception {
        Session session = jschConnectionManager.getSession();
        ChannelSftp channel = (ChannelSftp) session.openChannel("sftp");
        channel.connect();
        List<String> localFilePaths = new ArrayList<>();
        for (String filePath : filePaths) {
            String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);
            try {
                File fold = new File(localFileDir);
                if (!fold.exists()) {
                    fold.mkdirs();
                }
                // 创建本地文件的输出流
                localFilePaths.add(localFileDir + "/" + fileName);
                Path localFilePath = Paths.get(localFileDir + "/" + fileName);
                FileOutputStream fos = new FileOutputStream(localFilePath.toFile());
                // 从远程服务器下载文件到本地
                channel.get(filePath, fos);
                fos.close();  // 关闭文件输出流
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        channel.disconnect();
        return localFilePaths;
    }

    public void createRemoteDirAndFile(String localFilePath, String volumnPath, String dataPath)throws Exception  {
        Session session = jschConnectionManager.getSession();
        ChannelSftp channel = (ChannelSftp) session.openChannel("sftp");
        channel.connect();

        //创建容器工作空间目录
        channel.mkdir(volumnPath);
        channel.chmod(0777, volumnPath);
        //创建用户操作目录
        channel.mkdir(dataPath);
        channel.chmod(0777, dataPath);
        // 读取本地文件
        Path mainPath = Paths.get(localFilePath + "/main.py");
        FileInputStream fis = new FileInputStream(mainPath.toFile());
        channel.put(fis, volumnPath + "/main.py");

        Path workflowPath = Paths.get(localFilePath + "/workflow.py");
        FileInputStream fis1 = new FileInputStream(workflowPath.toFile());
        channel.put(fis1, volumnPath + "/workflow.py");

        //opengms的python包
        Resource resource = resourceLoader.getResource("classpath:static/config.ini");
        try (InputStream inputStream = resource.getInputStream()) {
            channel.put(inputStream, volumnPath + "/config.ini");
        } catch (IOException e) {
            e.printStackTrace();
            throw new Exception("Failed to upload config.ini", e);
        }

        uploadDirectory(channel, "static/ogmsServer", volumnPath + "/ogmsServer");

        // 新的模型调用包
        resource = resourceLoader.getResource("classpath:static/FastModelAPI.py");
        try (InputStream inputStream = resource.getInputStream()) {
            channel.put(inputStream, volumnPath + "/FastModelAPI.py");
        } catch (IOException e) {
            e.printStackTrace();
            throw new Exception("Failed to upload FastModelAPI.py", e);
        }

        channel.disconnect();
    }

    private void executeRemoteCommand(Session session, String command) throws Exception {
        ChannelExec channel = (ChannelExec) session.openChannel("exec");
        channel.setCommand(command);

        channel.setErrStream(System.err);
        channel.setInputStream(null);
        channel.connect();

        channel.disconnect();
    }
}

